# -*- coding: utf-8 -*-

import requests
import json
import datetime
import random

import base64


def access_token(base_url, app_key, app_secret):
    api = API(base_url)
    res = api.authen_token(app_key, app_secret)
    return res


class API(object):
    def __init__(self, base_url, app_key=None, app_secret=None, token=None, tin=None):
        self.base_url = base_url
        self.app_key = app_key
        self.app_secret = app_secret
        self.access_token = token
        self.tin = tin

    def json_call(self, url, params=None, data=None):
        if not params:
            params = {}
        if not data:
            data = {}

        base_url = self.base_url
        # timeout = self.timeout

        full_url = base_url + url

        headers = {"content-type": "application/json",
                   #    "credentials": "include"
                   }

        # print('json call:', full_url, params, data)

        rspd = requests.post(full_url, params=params,
                             data=json.dumps(data),
                             headers=headers)

        # print(full_url, params, data)

        res = json.loads(rspd.text)
        # print('res:', res,  type(res))

        return res

    def authen_token(self, app_key, app_secret):
        url = '/api/authen/token'

        params = {}
        data = {
            "appKey": app_key,
            "appSecret": app_secret,
        }

        res = self.json_call(url, params=params, data=data)
        return res

    def _call(self, url, content):
        url2 = url + '?access_token=' + self.access_token
        # print('_call', url2)

        zipCode = '0'
        encryptCode = '0'

        now = datetime.datetime.now()
        id_yyyymmddhhmmssffffff = now.strftime("%Y%m%d%H%M%S%f")[0:17]
        random_int = random.randint(0, 1000 * 1000 * 1000 * 1000 * 1000)
        random_str = '%015d' % random_int
        dataExchangeId = id_yyyymmddhhmmssffffff+random_str

        entCode = self.tin
        json_content = json.dumps(content)
        content = base64.b64encode(json_content.encode('utf-8'))
        content = content.decode('utf-8')

        # print('base64,,', content)

        params = {}
        data = {
            'zipCode': zipCode,
            'encryptCode': encryptCode,
            'dataExchangeId': dataExchangeId,
            'entCode': entCode,
            'content': content,
        }

        # print(data)

        res = self.json_call(url2, params, data)

        returnStateInfo = res['returnStateInfo']
        returnCode = returnStateInfo['returnCode']
        returnMessage = returnStateInfo['returnMessage']
        returnMessage = base64.b64decode(returnMessage)
        returnMessage = returnMessage.decode('utf-8')

        # 'returnStateInfo': {'returnCode': '0000',
        # 'returnMessage': '5aSE55CG5oiQ5YqfIQ=='},
        # 'entCode': '12100000400002435L'}

        if returnCode != '0000':
            print('returnCode', type(returnCode),  returnCode)
            print('returnMessage', type(returnMessage),  returnMessage)

            raise Exception({
                'code': returnCode,
                'message': returnMessage
            })

        # print('ok', res)

        returnContent = res['content']
        returnContent = base64.b64decode(returnContent)
        returnContent = returnContent.decode('utf-8')
        returnContent = json.loads(returnContent)
        # print('returnContent', returnContent)
        # print('returnContent', type(returnContent), returnContent)
        # print('returnContent', type(returnContent), returnContent)

        return returnContent

    def check_invoice_single(self, content):
        url = '/api/open-recipt/V1/CheckInvoiceSingle'
        # print(content)
        res = self._call(url, content)
        # print('check_invoice_single ok:', res)

        return_code = res['code']
        if return_code != '0000':
            raise Exception({
                'code': return_code,
                'message': res['message']
            })

        data = res['data']

        # data2 = format_invoice(data)

        return data
